home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
printing
/
lpr2-1.2e
/
lpr2-1
Wrap
Text File
|
1995-08-07
|
20KB
|
520 lines
#!/bin/sh
# LPR2 -- Utility to print postscript document on both sides.
VERSION='1.2e'
######################## LEGAL STUFF, LICENSE, ET AL. #########################
# COPYLEFT NOTICE:
# Copyright (c) 1994 Franτois-RenΘ "FarΘ" BΓn Rideau DDa(.ng-Vu~
# (rideau@ens.fr,rideau@frmap711.mathp7.jussieu.fr)
# LICENSE AGREEMENT:
# This program is distributed under *modified* the terms of the
# GNU General Public License (any official version you can find).
# Particularly,
# 0) You are mostly free to use and redistribute this program.
# 1) there is absolutely NO WARRANTY about what effect it can have
# on your software or hardware.
# 2) you may strip off any comment or useless characters and statements
# from this file, but only for personal use. But you shall not distribute
# a modified or stripped version.
# Just below are my modifications to the GPL...
# SMILEWARE
# This program is smileware:
# 1) if you use this program several times, if you modify it, or enhance it
# in any way, you should send me a note, letter, postcard, or even just an
# e-mail. This note should contain your feedback about your using this
# program, suggestions about improvements, enhancements, etc, if you have any.
# But even if you don't, a note/card/etc with just some kind words or a smiley
# is welcome.
# 2) if you use this program regularly, or reuse it more than three months
# after you originally used it, I morally bind you to pay for it.
# The exact amount you pay is up to you, but it shouldn't be less than one
# hundredth of what a typical commercial program costs near you, and not less
# than the expenses incurred for paying. Once you determined how much to pay,
# you should do one of the following with that money:
# a) give it all to the next beggar you meet (ain't there one just round the
# corner ?); if you think it's too much money for you to give him, well,
# firstly, you're paying for this program, so consider it's me giving your
# money to the beggar, and second, it will be fun to you to look his reaction.
# b) if you really don't want to give this money to this beggar, or if there's
# no beggar where you live, send your money to any charitable or ecological
# organization you *know* to be honest.
# c) if you won't give to a beggar, and don't trust any charitable or
# ecological organization, then send it to me, and I'll do it myself.
#
# My addresses are at the end of these comments.
########################### DESCRIPTION AND HELP #############################
# WHAT LPR2 IS MEANT TO BE:
# To save paper, and lighten you backpack, without lightening your purse by
# buying printers that already print documents on both sides, do use this
# program to print double sided documents.
# Not throwing away paper is good for just everyone throughout the world.
# Stop the spillage, help save the world, use LPR2 !
# Enhanced version 1.2 now works with *all* documents I've tried it with !!!
# WHAT LPR2 IS *NOT* MEANT TO BE:
# This program is NOT a full-featured program for manipulating postscript
# documents either. mpage, psutils, and commercial software from Adobe will do
# that for you. However, I've not tried commercial software, but all the free
# utilities I could find. And for the majority of the documents I've tried
# to manipulate, that I got from throughout the Internet (papers that were
# written using various software), none of these utilities would work properly:
# and wanted to print: sometimes it wouldn't work at all, or it would
# mirror the page, lose font information, or choke in the middle of the
# document (typically near the place some postscript documents was imported
# in the original paper: figure, picture, etc). LPR2 won't replace the
# multipage "n-up" features from the previous utilities (well it could be done,
# but not without a careful study of postscript), but at least it will provide
# a page selection mechanism that works on all reasonable documents: LPR2 has
# never failed on any published document it has been tried with yet (but it
# would be trivial to write some program specifically for lpr2 to fail).
# This program is NOT a "standalone" postscript interpreter either.
# You still need another PostScript interpreter to get it to work. The
# interpreter is typically just your PostScript printer, or GhostScript,
# or whatever. If you have a non-PostScript printer, the Printing-HOWTO
# (somewhere on all Linux sites) will explain you how to set up "lpr" to
# work with PostScript documents anyway, using GhostScript as the interpreter
# (that's free software).
# WHERE TO FIND THE LATEST VERSION
# The latest version should be available by anonymous ftp:
# * on "ftp://sunsite.unc.edu/pub/Linux/" and mirror linux sites,
# in subdirectory "system/Printing/"
# * on my own ftp site, "ftp://frmap711.mathp7.jussieu.fr/pub/scratch/rideau/"
# in subdirectory "lpr2/"
# * if you know any site where people would look for such programs, please
# tell me, so I can spread this utility.
# HOW IT WORKS:
# The shell part is only a wrapper to accept all the different options.
# The core of the program (the shell function redefshowpage) prepends some
# PostScript code to the file to print, that redefines "showpage" so that it
# will print every other page. According to the new showpage skipping the
# first page or not, we obtain one document for recto sides, and one another
# for verso sides. We then have to print it all...
# Note that as the program redefines *global* variables, it cannot be
# recursively called. But as the page selection function is programmable,
# such use isn't needed. If you know how to reliably use local variables
# in postscript, please tell me.
# There should not be any clash with variables from the postscript file to
# be printed; if however there was one, you can still modify those names in
# the postscript part of lpr2.
# INSTALLATION PROCEDURE:
# - gunzip lpr2
# - chmod 0755 lpr2
# - mv lpr2 /somewhere_in_my_PATH/bin/
# - edit the file to customize if need be (look for !!!! marks):
# the LPR= line should contain the name of a command or function that
# will print its PostScript standard input. I put "lpr" as the default.
# - Enjoy !
# USAGE:
# To print document "doc.ps", print odd pages on one side and even pages on
# the other.
#
# My HP LaserJet 4ML printer issues pages in the "right" order, i.e. the
# page on top exits on top. I also have to feed paper with verso (back) upward,
# and top of sheet near me. Thus, I have to print even pages first, then odd
# pages. That's what the default behaviour is.
#
# Rainer Blome (rainer@physik3.gwdg.de) says:
## My default `PostScript' printer, an HP LJ III, does emit pages in the
## `right' order (small page numbers on top), but does not feed verso. a
## stack of paper exits the printer exactly the same configuration as it has
## been put in the paper cassette.
## To get the desired result, however, i need the pages in this order, yes,
## but the empty side has to be in the position that will be printed on. the
## HP IV does that automatically, each page is reversed on every printing.
## Thus, `print on reverse side' with `emit in right order' is OK, as is
## `print on topside' with `emit in wrong order'. other combinations require
## reordering/reversal by hand.
#
# If you need some other behaviour, please tell me or correct it and send
# me feedback.
#
# Beware that there may be one odd page more than even pages. Sheets must be
# fed with verso on top. Default option (--all) does it.
#
# Thus, the usage is: feed blank sheets to the printer, mark one corner with
# a pencil to see how you will have to feed sheets again to print the other
# side. Then, print even pages. Insert printed pages back into the printer
# in the right order and side, as determined by the pencil, and
# print odd pages.
# MISFEATURES:
# First of all, this is a mixed /bin/sh and Postscript program; the existence
# of such languages is a bug in itself. Please send feedback to God so that
# this state of things changes.
# Because it uses /bin/sh, this program cannot reliably work with files
# whose name contain spaces, carriage returns, null characters, etc. But this
# is the case for most unix programs, so lpr2 is not *particularly* limiting
# in such sense.
# There is no soundness testing for the -p option, so beware and stick to
# the syntax; however, an error will most probably result in a run-time error
# at execution of the postscript program, so the document will be rejected
# without any page being printed.
# INVOCATION: lpr2 [options] files
#
# option what it means
# -1,-o,--odd "print only odd pages"
# -2,-e,--even "print only even pages"
# -c,--cond "the string just after this is the postscript condition for
# a page to be printed, e.g. '4 eq'"
# -s,--select "print only the page whose number follows '-s' "
# -p,--pages "print the pages listed after -p
# in a comma-separated list of the form i-j[%k],
# where i and j are first and/or last pages,
# and k is a step. -- not implemented"
# -a,--all "print even pages; prompt; print odd pages" (default)
# -P,--print "do send to printer, not to standard output"
# -N,--noprint "do not send to printer, but to standard output" (default)
# -r,--reverse "print odd pages; prompt; print even pages in reverse
# order" (beware: remove last sheet if odd number of pages)
# NOT IMPLEMENTED YET, and not to be soon, as it involves much
# more than just a postscript header. Use mpage or psrev (from
# the psutil package) if you need such thing. Unhappily, those
# packages are far less reliable than lpr2 v1.2
# -z define the printing program to be following argument
# e.g. -z lpr or -z cat
# -Z following argument is to pass to the printing program
# e,g, -Z "-lpr_option -second_lpr_option"
# -- stop parsing options: all the remaining arguments are filenames.
# THE AUTHOR:
# I'm no PostScript guru *at all*. It's my first (and certainly last)
# PostScript program. I've never read any Postscript book or official
# documentation or programming recommendation; only gs manpage and
# examples. Postscript looks like a very interesting language to me;
# very FORTH-like indeed. But whoever defined such lame semantics for binding
# only deserves shame.
# I developped this program under Linux using Ghostscript 2.6.1 in five
# minutes. I've actually spent much more time documenting it and transforming
# it into a shell utility than I did writing the postscript stuff. Just try
# to evaluate and compare the size of the postscript part, the size of the
# shell script part, and the size of the comments ;-)
# HOW WELL THE PROGRAM SHOULD BEHAVE:
# This program works very well for me.
# - you need a shell that supports shell functions (SYSV or SunOS shells do,
# while Ultrix shell doesn't). If yours doesn't work, try getting ksh, bash or
# better even, *zsh* (use option -fy for sh emulation) from the net.
# - The program should work on any well-behaved PostScript document (i.e. the
# kind of documents standard applications produce), but is reported to fail
# when used in combination with some dirty Postscript utilities. mpage by
# Mark P. Hahn 1988 is such dirty program that fails :( :(. Happily, newer
# versions of mpage already support page selection, so when mpage works,
# lpr2 is not needed.
# - You should be able to refeed the printer with its first output, and of
# course, be sure that no one else will use the printer while you are feeding
# the printer with the output for the verso side of the documents.
# - If your printer output pages in the reverse order, you're in for a double
# session of reordering pages :( :( :(
# HISTORY:
# version 0.0: just postcript code manually prepended to a document.
# developped with ghostscript.
# version 0.1: the same, but working (with the discovery of erasepage)
# version 1.0: a script that doesn't even work (I'm ashamed of that)-8
# version 1.1: the same, but bugs fixed:
# - cat <<"END" was used instead of cat<<END,
# and did not expand $1.
# - %! was forgotten on the first line of the document,
# which can make auto-detection of file format fail for lpr2
# documents.
# - "echo lpr" was also done instead of lpr :(
# And a new feature added:
# - if "-" or no file is given, lpr2 will work even with option
# "--all", by saving input in a file to reread it the second
# time. Exit and signals are trapped to rm it.
# version 1.1b: Help was increased thanks to the kind feedback of
# Warwick Hockley <hock@adhoc.apana.org.au>.
# Help options are supported.
# version 1.1c: bugs corrected: quotes not closed >8 ; run-time message
# modified
# version 1.1d: added arbitrary page selection
# version 1.2: used the ps2ppm PageCount trick using strings to escape
# save/restore sequences. lpr2 now works with all files
# I've tried it with !
# version 1.2b: Just understood why ps2ppm added 1000000 to page count.
# lpr2 now works after page 9 :)
# version 1.2c: added nicer page selection: page can be named as p...
# version 1.2d: merged feedback from Rainer Blome (rainer@physik3.gwgd.de):
# - removed the -P,--print "I changed my mind. Do print" option
# because it conflicted with a common printer option.
# - extended the description of how to reinsert paper.
# version 1.2e: - added the -p option
# - replaced the default behavior (print) by printing to stdout
# if any option is present. Restored option -P, with options
# -z and -Z to select printing command and default option
# behavior to "unknown option" instead of passing it blindly
# to lpr.
# TO DO
# - if we know some upper bound to the last page to be printed, put some
# "end execution" Postscript instruction for when this page is reached;
# of course, I should first find how this can in done in PostScript :)
# AUTHOR'S .SIGNATURE AND ADDRESSES:
#- , , _ v ~ ^ --
#- Fare -- rideau@clipper.ens.fr -- Francois-Rene Rideau -- +)ang-Vu Ban --
#- ' / . --
#MOOSE project member. OSL developer. | | /
#Dreams about The Universal (Distributed) Database. --- --- //
#Snail mail: 6, rue Augustin Thierry 75019 PARIS FRANCE /|\ /|\ //
#Phone: 033 1 42026735 /|\ /|\ /
#Join the TUNES project for a computing system based on computing freedom !
# TUNES is a Useful, Not Expedient System
#WWW page at URL: "http://www.eleves.ens.fr:8080/home/rideau/Tunes/"
########################## The Postscript stuff ##############################
redefshowpage ()
{
# have as argument condition on page to show
cat <<-END
%!PS-Adobe-3.0
/.show.this.page.p { $1 } bind def
/.page.number 1000001 7 string cvs def
/.showpage.orig /showpage load def
/.erasepage /erasepage load def
/.showpage.lpr2 {
2 dict begin
/p .page.number dup cvi dup 1 add 3 2 roll cvs pop 1000000 sub def
mark p
% (lpr2: showpage called for page ) print dup =only (.\n) print flush
.show.this.page.p
/c exch def cleartomark c
end
{ % (lpr2: showing page.\n) print flush
.showpage.orig }
{ % (lpr2: skipping page.\n) print flush
.erasepage }
ifelse
% (lpr2: showpage ended.\n) print flush
} def
%Redefine showpage...
/showpage { .showpage.lpr2 } bind def
END
}
########################## The shell functions ##############################
doprinteven ()
{
(redefshowpage "2 mod 0 eq" ; cat $FILES) | $SENDJOB
}
doprintodd ()
{
(redefshowpage "2 mod 1 eq" ; cat $FILES) | $SENDJOB
}
doprintcond ()
{
(redefshowpage "$COND" ; cat $FILES) | $SENDJOB
}
prompt ()
{
echo "$@" > /dev/tty
read dummy_answer < /dev/tty
}
doall ()
{
prompt '
Feed the printer with blank sheets.
If you don'"'"'t how to feed the printer again to achieve printing on
the "right" side, mark corners of the first sheets with a pencil.
When you'"'"'re done, press "Enter".
'
doprinteven
prompt '
First, do wait for the thing to have been printed.
When it'"'"'s done, press "Enter".
'
prompt '
Now, if your printer issues pages in the wrong order, you have a problem.
You'"'"'ll have to reorder everything twice. Next time, try --reverse option
if it'"'"'s implemented.
The first thing to do after having recovered the back sides of your printed
documents is to ensure that no one else will use the printer while you'"'"'re
printing on the other side.
When this is done, feed the printer back with the same sheets, but
place the sheets so that the other side will be printed (with the same top
of page). If your document has an odd number of page, add a blank sheet at
the end.
When you'"'"'re done, press "Enter".
'
doprintodd
}
doreverse ()
{
echo "NOT IMPLEMENTED YET" >&2
exit 4
}
calllpr ()
{
$LPR $LPROPTS
}
cleanexit () {
$RM $FILE
exit 1
}
ComputeEachCOND () {
C_COND_0 $1
COND="$COND1"
shift
for i ; do
C_COND_0 $i
COND="$COND"'
'"$COND1 or"
done
}
C_COND_0 () {
case "$1" in
"-%"*) : a ; IFS=" -%" ; C_COND_1 1 x $1 ;;
"-"*"%"*) : b ; IFS=" -%" ; C_COND_1 1 $1 ;;
*"-%"*) : d ; IFS=" -%" ; C_COND_2 $1 ;;
*"-"*"%"*) : e ; IFS=" -%" ; C_COND_1 $1 ;;
"-"*) : c ; IFS=" -%" ; C_COND_1 1 $1 1 ;;
*"%"*) : f ; IFS=" -%" ; C_COND_2 $1 ;;
*"-") : g ; IFS=" -%" ; C_COND_1 $1 x 1 ;;
*"-"*) : h ; IFS=" -%" ; C_COND_1 $1 1 ;;
"%"*) : i ; IFS=" -%" ; C_COND_1 1 x $1 ;;
*) : j ; IFS=" -%" ; C_COND_1 $1 $1 1 ;;
esac
}
C_COND_1 () {
C_COND_n $*
}
C_COND_2 () {
C_COND_m $*
}
C_COND_m () {
C_COND_n $1 x $2
}
C_COND_n () {
IFS=" "
if [ "$1" = "$2" ] ; then
COND1="p $1 eq"
else
if [ "$1" != 1 ] ; then
COND1="p $1 ge"
if [ "x$2" != "xx" ] ; then
COND1="$COND1 p $2 le and"
fi
else
if [ "x$2" != "xx" ] ; then
COND1="p $2 le"
else
COND1=true
fi
fi
fi
if [ "$3" != 1 ] ; then
COND1="$COND1 p $1 sub $3 mod 0 eq and"
fi
}
ComputeCOND () {
IFS=" ," ; ComputeEachCOND $1
IFS=" "
}
######################### The command line interface ########################
LPR="lpr" # !!!! replace with your standard printing command
# may be just "cat > /dev/lp1". lpr should be fine.
RM="rm" # !!!! replace with your standard file deletion command
# may be "/bin/rm -f -", but rm should be fine.
# These should be ok and not need any modification
TODO=doall
LPROPTS=
FILES=
SENDJOB=cat # calllpr
ParseOpts () {
GOTOPTS=n
while [ -n "$*" ] ; do
i="$1" ; shift
case "$i" in
-a|--all) GOTOPTS=y ; TODO=doall ; SENDJOB=calllpr ;;
-r|--reverse) GOTOPTS=y ; TODO=doreverse ; SENDJOB=calllpr ;;
-N|--noprint) GOTOPTS=y ; SENDJOB=cat ;;
-P|--print) GOTOPTS=y ; SENDJOB=calllpr ;;
-1|-o|--odd) GOTOPTS=y ; TODO=doprintodd ;;
-2|-e|--even) GOTOPTS=y ; TODO=doprinteven ;;
-c|--cond) GOTOPTS=y ; TODO=doprintcond ; COND="$1" ; shift ;;
-s|--select) GOTOPTS=y ; TODO=doprintcond ; COND="$1 eq" ; shift ;;
-p|--pages) GOTOPTS=y ; TODO=doprintcond ; ComputeCOND $1 ; shift ;;
-z) GOTOPTS=y ; LPR="$2" ; shift 2 ;;
-Z) GOTOPTS=y ; LPROPTS="$LPROPTS $2" ; shift 2 ;;
--) FILES="$FILES $*" ; shift $# ;;
-v) echo "LPR2 v$VERSION" ; exit 0 ;;
-V|--version) echo "LPR2 -- version $VERSION" ; exit 0 ;;
-h|-"?"|--help) echo "Run command \`\`more $0''" \
"for help about this program."
exit 0 ;;
-*) echo "Unknow option \`\`$i''." >&2
echo "Read file $0 for help." >&2
exit 3 ;;
*) FILES="$FILES $i" ;;
esac
done
if [ "$GOTOPTS" = "n" ] ; then TODO=doall ; SENDJOB=calllpr ; fi
}
DoIt () {
: '":" is for debugging'
: LPR=$LPR
: TODO=$TODO
: SENDJOB=$SENJOB
: LPROPTS=$LPROPTS
: FILES=$FILES
case "$SENDJOB$TODO$FILES" in
catdoall*|catdoreverse*)
echo "Incompatible options" ;
exit 1 ;;
calllprdoall*" - "*|calllprdoreverse*" - "*|calllprdoall|calllprdoreverse)
FILE=/tmp/lpr2-$$
trap cleanexit EXIT HUP TERM
cat > $FILE
FILES=$FILE $FILES
$TODO
;;
*) $TODO
;;
esac
}
ParseOpts "$@"
DoIt